using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SpaceWolf.Shaders
{
    public class ParticleShader :ShaderEffect
    {
        #region Variables
        // Shortcuts for accessing frequently changed effect parameters.
        EffectParameter effectViewParameter;
        EffectParameter effectProjectionParameter;
        EffectParameter effectViewportHeightParameter;
        EffectParameter effectTimeParameter;
        EffectParameter effectTexture;

        Texture2D texture;
        #endregion

        public ParticleShader(String FileName)
            : base(FileName)
        {
        }
        
        protected override void GetParameters()
        {
            base.GetParameters();
            effectViewParameter = effect.Parameters["View"];
            effectProjectionParameter = effect.Parameters["Projection"];
            effectViewportHeightParameter = effect.Parameters["ViewportHeight"];
            effectTimeParameter = effect.Parameters["CurrentTime"];
            effectTexture = effect.Parameters["Texture"];
            

            // Look up shortcuts for parameters that change every frame.
            // To Do: inlset code here
        }

        public void InitializeSettings(Particle3D.ParticleSettings settings)
        {
            EffectParameterCollection parameters = effect.Parameters;

            // Set the values of parameters that do not change.
            parameters["Duration"].SetValue((float)settings.Duration.TotalSeconds);
            parameters["DurationRandomness"].SetValue(settings.DurationRandomness);
            parameters["Gravity"].SetValue(settings.Gravity);
            parameters["EndVelocity"].SetValue(settings.EndVelocity);
            parameters["MinColor"].SetValue(settings.MinColor.ToVector4());
            parameters["MaxColor"].SetValue(settings.MaxColor.ToVector4());

            parameters["RotateSpeed"].SetValue(
                new Vector2(settings.MinRotateSpeed, settings.MaxRotateSpeed));

            parameters["StartSize"].SetValue(
                new Vector2(settings.MinStartSize, settings.MaxStartSize));

            parameters["EndSize"].SetValue(
                new Vector2(settings.MinEndSize, settings.MaxEndSize));

            // Load the particle texture, and set it onto the effect.
            texture = BaseGame.ContentManager.Load<Texture2D>(settings.TextureName);

            //parameters["Texture"].SetValue(texture);

            // Choose the appropriate effect technique. If these particles will never
            // rotate, we can use a simpler pixel shader that requires less GPU power.
            string techniqueName;

            if ((settings.MinRotateSpeed == 0) && (settings.MaxRotateSpeed == 0))
                techniqueName = "NonRotatingParticles";
            else
                techniqueName = "RotatingParticles";

            effect.CurrentTechnique = effect.Techniques[techniqueName];

        }

        public void Render(float currentTime,SpaceWolf.BaseGame.RenderHandler renderCode)
        {
            effectViewParameter.SetValue(BaseGame.ViewMatrix);
            effectProjectionParameter.SetValue(BaseGame.ProjectionMatrix);

            effectViewportHeightParameter.SetValue(BaseGame.Device.Viewport.Height);
            effectTimeParameter.SetValue(currentTime);
            effectTexture.SetValue(texture);
            effect.Begin();
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Begin();
                renderCode();
                pass.End();
            }

            effect.End();

            // Reset a couple of the more unusual renderstates that we changed,
            // so as not to mess up any other subsequent drawing.
            SpaceWolf.BaseGame.Device.RenderState.PointSpriteEnable = false;
            SpaceWolf.BaseGame.Device.RenderState.DepthBufferWriteEnable = true;
        }// Draw
    }
}
